/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.github.florent37.camerafragment.internal.controller.impl;

import com.github.florent37.camerafragment.configuration.Configuration;
import com.github.florent37.camerafragment.configuration.ConfigurationProvider;
import com.github.florent37.camerafragment.internal.controller.CameraController;
import com.github.florent37.camerafragment.internal.controller.view.CameraView;
import com.github.florent37.camerafragment.internal.manager.CameraManager;
import com.github.florent37.camerafragment.internal.manager.impl.Camera1Manager;
import com.github.florent37.camerafragment.internal.manager.listener.CameraCloseListener;
import com.github.florent37.camerafragment.internal.manager.listener.CameraOpenListener;
import com.github.florent37.camerafragment.internal.manager.listener.CameraPhotoListener;
import com.github.florent37.camerafragment.internal.manager.listener.CameraVideoListener;
import com.github.florent37.camerafragment.internal.ui.view.AutoFitSurfaceView;
import com.github.florent37.camerafragment.internal.utils.CameraHelper;
import com.github.florent37.camerafragment.internal.utils.Log;
import com.github.florent37.camerafragment.internal.utils.Size;
import com.github.florent37.camerafragment.internal.utils.Toast;
import com.github.florent37.camerafragment.listeners.CameraFragmentResultListener;

import ohos.aafwk.ability.fraction.FractionAbility;
import ohos.aafwk.content.Intent;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.graphics.SurfaceOps;
import ohos.app.Context;

import java.io.File;

/**
 * 相机操控1
 *
 * @since 2021-05-24
 */
public class Camera1Controller implements CameraController<Integer>, CameraOpenListener<Integer, SurfaceOps.Callback>,
    CameraPhotoListener, CameraCloseListener<Integer>, CameraVideoListener {
    private static final String TAG = "Camera1Controller";
    private static final int NEGATIVE = -1;
    private final Context context;
    private int currentCameraId;
    private ConfigurationProvider configurationProvider;
    private CameraManager<Integer, SurfaceOps.Callback> cameraManager;
    private CameraView cameraView;
    private File outputFile;

    /**
     * 构造函数
     *
     * @param context 上下文
     * @param cameraView 相机视图
     * @param configurationProvider 配置项提供
     */
    public Camera1Controller(Context context, CameraView cameraView, ConfigurationProvider configurationProvider) {
        this.context = context;
        this.cameraView = cameraView;
        this.configurationProvider = configurationProvider;
    }

    /**
     * 初始化创建相机
     *
     * @param stateIntent intent状态
     * @param surfaceProvider 线性布局
     * @param fractionAbility Ability页面
     */
    @Override
    public void onCreate(Intent stateIntent, DirectionalLayout surfaceProvider, FractionAbility fractionAbility) {
        cameraManager = new Camera1Manager();
        cameraManager.initializeCameraManager(configurationProvider, context);
        setCurrentCameraId(cameraManager.getFaceBackCameraId());
        cameraManager.getPhotoQualityOptions();
        cameraManager.getVideoQualityOptions();
        cameraManager.initSurfaceComponent(surfaceProvider, fractionAbility, this);
    }

    private void setCurrentCameraId(Integer cameraId) {
        this.currentCameraId = cameraId;
        cameraManager.setCameraId(cameraId);
    }

    /**
     * 失去焦点时释放相机,重新打开相机
     */
    @Override
    public void onPause() {
        cameraManager.closeCamera(this);
    }

    @Override
    public void onDestroy() {
        cameraManager.releaseCameraManager();
    }

    @Override
    public void takePhoto(CameraFragmentResultListener callback) {
        takePhoto(callback, null, null);
    }

    @Override
    public void takePhoto(CameraFragmentResultListener callback, String direcoryPath, String fileName) {
        outputFile = CameraHelper.getOutputMediaFile(context, Configuration.MEDIA_ACTION_PHOTO, direcoryPath, fileName);
        cameraManager.takePhoto(outputFile, this, callback);
    }

    @Override
    public void startVideoRecord() {
        startVideoRecord(null, null);
    }

    @Override
    public void startVideoRecord(String direcoryPath, String fileName) {
        outputFile = CameraHelper.getOutputMediaFile(context, Configuration.MEDIA_ACTION_VIDEO, direcoryPath, fileName);
        cameraManager.startVideoRecord(outputFile, this);
    }

    @Override
    public void stopVideoRecord(CameraFragmentResultListener callback) {
        cameraManager.stopVideoRecord(callback);
    }

    @Override
    public boolean isVideoRecording() {
        return cameraManager.isVideoRecording();
    }

    @Override
    public void switchCamera(@Configuration.CameraFace final int cameraFace) {
        final int backCameraId = cameraManager.getFaceBackCameraId();
        final int frontCameraId = cameraManager.getFaceFrontCameraId();
        final int currentId = cameraManager.getCurrentCameraId();

        if (cameraFace == Configuration.CAMERA_FACE_REAR && backCameraId != NEGATIVE) { // 后置摄像头
            setCurrentCameraId(backCameraId);
            cameraManager.closeCamera(this);
        } else if (frontCameraId != NEGATIVE && frontCameraId != currentId) { // 前置摄像头
            setCurrentCameraId(frontCameraId);
            cameraManager.closeCamera(this);
        }
    }

    @Override
    public void setFlashMode(@Configuration.FlashMode int flashMode) {
        cameraManager.setFlashMode(flashMode);
    }

    @Override
    public void switchQuality() {
        cameraManager.closeCamera(this);
    }

    /**
     * 获取相机设备数量
     *
     * @return int整数
     */
    @Override
    public int getNumberOfCameras() {
        return cameraManager.getNumberOfCameras();
    }

    @Override
    public int getMediaAction() {
        return configurationProvider.getMediaAction();
    }

    @Override
    public void setMediaAction(int mediaAction) {
        configurationProvider.setMediaAction(mediaAction);
        cameraManager.setMediaAction(mediaAction);
    }

    @Override
    public File getOutputFile() {
        return outputFile;
    }

    @Override
    public int getCurrentCameraId() {
        return currentCameraId;
    }

    /**
     * 相机打开
     *
     * @param openedCameraId 相机Id
     * @param previewSize 预览大小
     * @param surfaceCallback 预览回调
     */
    @Override
    public void onCameraOpened(Integer openedCameraId, Size previewSize, SurfaceOps.Callback surfaceCallback) {
        cameraView.updateUiForMediaAction(configurationProvider.getMediaAction());
        cameraView.updateCameraPreview(previewSize, new AutoFitSurfaceView(context, surfaceCallback));
        cameraView.updateCameraSwitcher(getNumberOfCameras());
    }

    @Override
    public void onCameraOpenError() {
        // 后面再调试
        Log.error(TAG, "相机打开失败");
    }

    @Override
    public void onCameraClosed(Integer closedCameraId) {
        cameraView.releaseCameraPreview();
        cameraManager.openCamera(context, closedCameraId, this);
    }

    @Override
    public void onPhotoTaken(File photoFile, CameraFragmentResultListener callback) {
        cameraView.onPhotoTaken(callback);
    }

    @Override
    public void onPhotoTakeError() {
        Toast.show(context, "拍照失败");
    }

    @Override
    public void onVideoRecordStarted(Size videoSize) {
        cameraView.onVideoRecordStart(videoSize.getWidth(), videoSize.getHeight());
    }

    @Override
    public void onVideoRecordStopped(File videoFile, CameraFragmentResultListener callback) {
        cameraView.onVideoRecordStop(callback);
    }

    /**
     * 获取相机管理
     *
     * @return CameraManager 相机管理者
     */
    @Override
    public CameraManager getCameraManager() {
        return cameraManager;
    }

    @Override
    public CharSequence[] getVideoQualityOptions() {
        return cameraManager.getVideoQualityOptions();
    }

    @Override
    public CharSequence[] getPhotoQualityOptions() {
        return cameraManager.getPhotoQualityOptions();
    }

    /**
     * 打开闪光灯
     */
    @Override
    public void openFlashLight() {
        cameraManager.setFlashMode(Configuration.FLASH_MODE_ON);
    }

    /**
     * 关闭闪光灯
     */
    @Override
    public void closeFlashLight() {
        cameraManager.setFlashMode(Configuration.FLASH_MODE_OFF);
    }

    @Override
    public void setScreenRotation(int degrees) {
        cameraManager.setScreenRotation(degrees);
    }

    @Override
    public void releaseCamera() {
        cameraManager.releaseCameraResource();
    }

    @Override
    public void openCamera() {
        cameraManager.openCamera(context, currentCameraId, this);
    }
}
